<?php
class MutilHttpRequest {
    private $data;
    private $timeout = 60;

    public function __construct($data) {
        $this->data = $data;
        return $this;
    }

    public static function setData($data) {
        return new MutilHttpRequest($data);
    }

    public function start() {
        if (!$this->data || !is_array($this->data)) {
            return FALSE;
        }
        $handle = curl_multi_init(); //建立批处理
        foreach ($this->data as $index => $item) {
            $replace = array(
                'http://www.7ymm.com/uploads/' => 'http://61.143.198.80:52/uploads1/',
                'http://img.taotuwu.com/' => 'http://ttw.tukuzhan.com/',
                'http://pic.kongjun.cc/' => 'http://http://pic.jiukuaiyou.co:8088/',
                'http://www.ishowx.com/uploads/' => 'http://tu.ishowx.com/',
                'http://www.meinvaa.com/uploads/' => 'http://61.143.198.80:52/uploads2/',
                'http://www.23xmn.com/' => 'http://www.aimmxiu.com/',
                'http://www.kongjun.cc/' => 'http://pic2.jiukuaiyou.co:8089/',
                'http://www.mm5mm.com/' => 'http://mm.bestful.net/',
                'http://gamezone.qq.com/' => 'http://games.qq.com/',
                'http://trueimages.ru/' => 'http://cs1.trueimages.ru/',
                'http://s171.photobucket.com/' => 'http://i171.photobucket.com/',
                'http://acidcow.com/' => 'http://cdn.acidcow.com/',
                'http://pic.6188.com/' => 'http://www.6188.com/',
                'http://pics.nddaily.com/' => 'http://pics.oeeee.com/',
                'http://www.taihainet.com/news/' => 'http://epaper.taihainet.com/newspic/',
            );
            $this->data[$index]['pic_detail_url'] = $item['pic_detail_url'] = strtr($item['pic_detail_url'], $replace);
            echo '[准备获取' . $index . ']' . $item['pic_detail_url'] . "\n";
            $curls[$index] = $this->addHandle($handle, $item['pic_detail_url']);
        }
        $this->execHandle($handle);
        foreach ($this->data as $index => $item) {
            $content = curl_multi_getcontent($curls[$index]);
            writeFile($item, $content, curl_getinfo($curls[$index]));
            curl_multi_remove_handle($handle, $curls[$index]); //释放子句柄
        }
        curl_multi_close($handle); //关闭批处理
    }

    public function addHandle($handle, $url) {
        $curl = curl_init();
        $options = array(
            CURLOPT_URL => $url,
//            CURLOPT_TIMEOUT => $this->timeout,
            CURLOPT_RETURNTRANSFER => TRUE,
            CURLOPT_CONNECTTIMEOUT => 10,
        );
        curl_setopt_array($curl, $options);
        curl_multi_add_handle($handle, $curl); //添加子句柄到批处理
        return $curl;
    }

    //执行批处理，直到批处理执行结束
    public function execHandle($handle) {
        do{
            curl_multi_exec($handle, $still_running);
        } while ($still_running);
    }

}

//写将图片写入文件
function writeFile($data, $fileData, $curlInfo) {
    if ($fileData) {
        $data['pic_tag'] = strtr(trim($data['pic_tag']), array('/' => '-', ' ' => ''));
        $data['pic_category'] = strtr(trim($data['pic_category']), array('/' => '-', ' ' => ''));
        $data['pic_album'] = strtr(trim($data['pic_album']), array('/' => '-', ' ' => ''));
        $directory = 'images/' . $data['pic_tag'] . '/' . $data['pic_category'] . '/' . $data['pic_album'];
        $url = $data['pic_detail_url'];
        $filename = getFilename($url, $directory);

        $realFilename = $directory . '/' . $filename;
        if ($filename) {
            if (($status = $curlInfo['http_code']) == 200) {
                switch ($curlInfo['content_type']) {
                    case 'image/jpeg' :
                    case 'image/jpg' :
                        $realFilename .= '.jpg';
                        break;
                    case 'image/gif' :
                        $realFilename .= '.gif';
                        break;
                    case 'image/png' :
                        $realFilename .= '.png';
                        break;
                    case 'image/bmp' :
                        $realFilename .= '.bmp';
                        break;
                    default:
//                        $data = array(
//                            ':is_download' => -2, //文件扩展名不对
//                            ':pic_local_url' => '',
//                            ':id' => $data['id'],
//                        );
                        $path = explode('/', $data['pic_detail_url']);
                        if (!$path[count($path) - 1]) {
                            $path = array_pop(array_pop($path));
                        } else {
                            $path = array_pop($path);
                        }
                        if (strpos($path, '.')) {
                            $realFilename .= '.' . array_pop(explode('.', $path));
                        } else {
                            $realFilename .= '.jpg';
                        }
                        echo $directory . "\n";
                        $status = -3; //文件扩展名不对，但是已经下载
                        echo '[非法类型]文件' . $url . '类型非法' . $curlInfo['content_type'] . "\n";
//                        updateDatabase($data);
//                        return FALSE;
                }
//                $status = 1;
                if (!is_dir($directory)) {
                    mkdir($directory, 0777, TRUE);
                }

                if ($curlInfo['size_download'] >= 51200 && file_put_contents($realFilename, $fileData)) {
                    $data = array(
                        ':is_download' => $status, //直接记录状态码，成功记录1，否则记录状态码
                        ':pic_local_url' => $realFilename,
                        ':id' => $data['id'],
                    );
                    echo '[下载成功]文件' . $realFilename . '下载成功|size_download:' . intval($curlInfo['size_download'] / 1024) . "K\n";
                } else {
                    try {
                        if (count(scandir($directory)) <= 2) {//如果是空文件夹
                            @rmdir($directory);
                        }
                    } catch (Exception $exc) {
                        echo '[出现错误]' . $exc->getTraceAsString() . "文件夹删除失败\n";
                    }

                    $data = array(
                        ':is_download' => -1, //获取成功，写入文件失败,或者图片太小
                        ':pic_local_url' => '',
                        ':id' => $data['id'],
                    );
                    echo '[文件写入失败]文件' . $realFilename . '写入失败' . "\n";
                }
            } elseif ($status) {
                $data = array(
                    ':is_download' => $status, //直接记录状态码，成功记录1，否则记录状态码
                    ':pic_local_url' => '',
                    ':id' => $data['id'],
                );
                echo '[文件获取失败]文件' . $url . '下载失败|' . $status . "\n";
            } else {
                $data = array(
                    ':is_download' => 2, //死链
                    ':pic_local_url' => '',
                    ':id' => $data['id'],
                );
                echo '[死链接?]文件' . $url . '下载失败' . "\n";
            }
        } else {
            $data = array(
                ':is_download' => -2, //文件名不对
                ':pic_local_url' => '',
                ':id' => $data['id'],
            );
        }
    } else {
        echo '[下载失败]id' . $data['id'] . '|文件' . $data['pic_detail_url'] . '下载失败' . "\n";
        $data = array(
            ':is_download' => 2,
            ':pic_local_url' => '',
            ':id' => $data['id'],
        );
    }
    updateDatabase($data);
}

//更新数据库字段信息
function updateDatabase($data) {
    global $stmt2;
    $stmt2->execute($data);
}

//格式化图片文件名
function getFilename($url, $directory) {
    deleteHadArgsFile($url, $directory);
    if (strpos($url, 'https://') === 0) {
        $search = 'https://';
    } else {
        $search = 'http://';
    }
    $url = explode($search, $url);
    $url = $search . array_pop($url);
    $url = trim($url);
    $url = trim($url, '?/=&'); //有些图床文件地址末尾为/
    $file = explode('/', $url);
    if ((($f = array_pop($file)) == 'image.jpg' || strpos($url, 'http://t1.qpic.cn') === 0 ) && strpos($f, '.')) {
        $filename = strtr(array_pop($file), array('?' => '_', '&' => '_', '.' => '_', '=' => '_'));
        echo '特殊处理的文件' . "\n";
    } else {
        $filename = strtr(array_pop(explode('/', $url)), array('?' => '_', '&' => '_', '.' => '_', '=' => '_'));
    }
    if (checkLocalUrl($directory . '/' . $filename)) {
        $rand = range('a', 'z');
        shuffle($rand);
        $rand = implode('', $rand);
        $len = rand(5, 22);
        $filename = substr($rand, $len, 5) . rand(100, 999) . '_' . $filename;
    }
    $filename = strtr($filename, array('_jpg' => '', '_gif' => '', '_png' => ''));
    return $filename;
}

function checkLocalUrl($url) {
    global $stmt;
    $count = $stmt->execute(array(':pic_local_url' => $url));
    if ($count['count']) {
        return TRUE;
    }
    return FALSE;
}

//删除带有参数的文件
function deleteHadArgsFile($url, $directory) {
    $imgNameArray = explode('/', $url);
    $imgName = array_pop($imgNameArray);
    if (!$imgName) {
        $imgName = array_pop($imgNameArray);
        if (strpos($imgName, '.') === FALSE) {
            $imgName .= '.jpg';
        }
    }
    if (strpos($imgName, '?')) {
        $filename = $directory . '/' . $imgName;
        if (file_exists($filename)) {
            unlink($filename);
            echo '[删除成功]参数文件删除成功';
        }
    }
}
$table = 'sex8';
$dsn = "mysql:host=localhost;dbname=bhdw";
$username = 'root';
$password = '123456';
$options = array(PDO::MYSQL_ATTR_INIT_COMMAND => "SET NAMES 'UTF8';");
$dbConnection = new PDO($dsn, $username, $password, $options);
$stmt = $dbConnection->prepare('SELECT COUNT(*) AS count FROM ' . $table . ' WHERE pic_local_url=:pic_local_url');
$stmt2 = $dbConnection->prepare('UPDATE ' . $table . ' SET is_download = :is_download,pic_local_url=:pic_local_url WHERE id=:id');
while ($list = $dbConnection->query('SELECT id,pic_tag,pic_category,pic_detail_url,pic_album FROM ' . $table . ' WHERE is_download=0 ORDER BY id DESC LIMIT 10')->fetchAll(PDO::FETCH_ASSOC)) {
    $t = time();
    echo '开始:' . $t . "\n";
    MutilHttpRequest::setData($list)->start();
    echo '耗时:' . (time() - $t) . "\n";
}
?>
